﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;

namespace Microsoft.OpportunityPortal
{
    /// <summary>
    /// This class is used to handle the Opportunity Request events and perform
    /// operations such as creating opportunity site, updating the usage count, etc.
    /// </summary>
    public class OpportunityRequest
    {
        /// <summary>
        /// Returns site URL
        /// </summary>
        /// <param name="title"></param>
        /// <returns></returns>
        public static string CreateSite(string title, string rootSiteURL, SPWebTemplate webTemplate, string description,
            SPFieldUserValueCollection ownerUsers, SPFieldUserValueCollection teamUsers)
        {
            string oppSiteURL = string.Empty;

            try
            {
                using (SPSite site = new SPSite(rootSiteURL))
                {
                    using (SPWeb web = site.OpenWeb())
                    {
                        SPWeb opportunityWeb = web.Webs.Add(title, title, description, 1033, webTemplate, false, false);

                        if (opportunityWeb != null)
                        {
                            oppSiteURL = opportunityWeb.Url;

                            // Breaks the permission inheritance
                            opportunityWeb.BreakRoleInheritance(true);

                            // Create unique group name
                            string groupName = opportunityWeb.Title; // Opportunity Name
                            string ownerGroupName = string.Empty;
                            string memberGroupName = string.Empty;

                            if (opportunityWeb.ParentWeb != null)
                            {
                                // Portal Name
                                groupName = opportunityWeb.ParentWeb.Title + "_" + groupName;

                                // BU Name
                                if (opportunityWeb.ParentWeb.ParentWeb != null)
                                {
                                    groupName = opportunityWeb.ParentWeb.ParentWeb.Title + "_" + groupName;
                                }

                                ownerGroupName = groupName + " Owners";
                                memberGroupName = groupName + " Members";
                            }
                            else
                            {
                                ownerGroupName = "Owners";
                                memberGroupName = "Viewers";
                            }

                            // Creates owner group and add users
                            SPOperations.CreateGroup(web.Url, opportunityWeb.Url, ownerGroupName, "Full Control", SPRoleType.Administrator, ownerUsers,
                                false, ownerGroupName);

                            // Create Members group and add users. Also make the ownerGroupName as the group owner
                            SPOperations.CreateGroup(web.Url, opportunityWeb.Url, memberGroupName, "Contribute", SPRoleType.Contributor, teamUsers,
                                false, ownerGroupName);
                        }
                    }
                }


            }
            catch (SPException expn)
            {
                Dictionary<string, string> errorLog = new Dictionary<string, string>();
                errorLog.Add("Title", "Error_" + DateTime.Now.ToLongTimeString());
                errorLog.Add("Description", string.Format("StackTrace={0},Message={1}", expn.StackTrace, expn.Message));
                errorLog.Add("EventType", "Error");

                SPOperations.AddUpdateListItem(rootSiteURL, "Logger", errorLog, SPEventType.Add);

                errorLog = new Dictionary<string, string>();
                errorLog.Add("Title", "Error_" + DateTime.Now.ToLongTimeString());
                errorLog.Add("Description", "Error thrown while provisioning site..." + title);
                errorLog.Add("EventType", "Error");

                SPOperations.AddUpdateListItem(rootSiteURL, "Logger", errorLog, SPEventType.Add);  
            }
            return oppSiteURL;
        }

        /// <summary>
        /// Processes Opportunity request events such as provisioning sites.
        /// </summary>
        /// <param name="properties"></param>
        /// <returns></returns>
        public static bool ProcessOpportunityRequestEvent(SPItemEventProperties properties)
        {
            string title = properties.ListItem["Title"].ToString();

            try
            {
                // Check if the Workflow status is changed to Submitted. if yes then only provision the site.
                if (!(true == properties.ListItem.Fields.ContainsField("Opportunity Status") &&
                    properties.ListItem["Opportunity Status"] != null &&
                    string.Compare("Approved", properties.ListItem["Opportunity Status"].ToString(), true) == 0))
                {
                    // Workflow status is not Submitted.
                    return true;
                }

                // Get Web Template 
                SPWebTemplateCollection webTemplates = properties.Web.GetAvailableWebTemplates(1033);
                SPWebTemplate webTemplate = (from SPWebTemplate t in webTemplates where t.Title == "Opportunity Site Template" select t).FirstOrDefault();

                // Check if the Title field is present or not.
                if (webTemplate != null && true == properties.ListItem.Fields.ContainsField("Title") &&
                    true == properties.ListItem.Fields.ContainsField("Opportunity Desc"))
                {
                    SPFieldUserValueCollection ownerUsers = null;
                    SPFieldUserValueCollection teamUsers = null;
                    string description = title;

                    // Get the opportunity owner users
                    if (properties.ListItem["OppOwner"] != null &&
                        (properties.ListItem["OppOwner"] as SPFieldUserValueCollection).Count > 0)
                    {
                        ownerUsers = (properties.ListItem["OppOwner"] as SPFieldUserValueCollection);
                    }

                    // Get the opportunity team users
                    if (properties.ListItem["OpportunityTeam"] != null &&
                        (properties.ListItem["OpportunityTeam"] as SPFieldUserValueCollection).Count > 0)
                    {
                        teamUsers = (properties.ListItem["OpportunityTeam"] as SPFieldUserValueCollection);
                    }

                    // Use the opportunity ID field for site URL. Opportunity ID will be a unique field.
                    string opportunityID = "Opp-" + properties.ListItem["ID"].ToString();
                    string customerID = "Cust-" + properties.ListItem["ID"].ToString();
                    string siteURL = OpportunityRequest.CreateSite(title, properties.WebUrl, webTemplate, description, ownerUsers, teamUsers);

                    SPListItem item = properties.ListItem;

                    if (false == string.IsNullOrEmpty(siteURL) && item.Fields.ContainsField("OpportunityURL"))
                    {                        
                        item["OpportunityURL"] = siteURL;
                        item["URL"] = siteURL;
                        item["OppID"] = opportunityID;
                        item["CustomerID"] = customerID;
                        item.Update();
                        PerformAdhocOps(siteURL, properties.Web.Url);
                    }
                }
            }
            catch (SPException expn)
            {
                Dictionary<string, string> errorLog = new Dictionary<string, string>();
                errorLog.Add("Title", "Error_" + DateTime.Now.ToLongTimeString());
                errorLog.Add("Description", string.Format("StackTrace={0},Message={1}", expn.StackTrace, expn.Message));
                errorLog.Add("EventType", "Error");

                SPOperations.AddUpdateListItem(properties.WebUrl, "Logger", errorLog, SPEventType.Add);
                return false;
            }

            return true;
        }

        /// <summary>
        /// Performs adhoc operations post opportunity subsite creation such as making the Title column hidden.
        /// </summary>
        /// <param name="siteURL"></param>
        public static void PerformAdhocOps(string siteURL, string parentSiteURL)
        {
            // Make the Title field hidden in Case Study Reference list
            string listName = "Case Study Reference";
            string columnName = "Title";
            SPOperations.HideField(siteURL, listName, columnName);

            // Update the lookup column
            //SPOperations.UpdateLookupField(siteURL, listName, "Case Study Reference");

            // UPdate the view to add Case Study Reference column
            //List<string> columnNames = new List<string>();
            //columnNames.Add("Case Study Reference");
            //SPOperations.AddFieldToView(siteURL, listName, columnNames);
        }
    }
}
